// Tree node klasse

#ifndef TreeNode_h__
#define TreeNode_h__

class DXDevice;
class GameEngine;
class EffectShadow;
class NxActor;

/**
* Met MeshDesc kan je vershillende instellingen meegeven aan de mesh
* @author Ruben Rigole
*/
/** 
* @todo PhysX in de TreeNode steken
*/
class MeshDesc
{
public:
	/** 
	* Constructor, Zet castShadows op false en state op static.
	*/
	MeshDesc() {castShadow = false; state = PhysxStatic; ownRender = false; animated = false;}
	
	/** 
	* Destructor
	*/
	virtual ~MeshDesc() {}

	
	enum PhysxState { PhysxStatic, PhysxDynamic, PhysxGhost };
	bool castShadow;
	PhysxState state;
	tstring name;
	bool inLib;
	bool ownRender;
	bool animated;
	tstring diffuseMap;
	tstring normalMap;
	tstring specMap;
	int id;
};

/**
* Dit is de basis klasse van ieder object in het spel.
* Deze zorgt voor het verplaatsen, roteren en scalen van een object.
* @author Ruben Rigole
*/
class TreeNode
{
public:
	/**
	* Maakt de TreeNode aan.
	*/
	TreeNode();
	
	/**
	* Vernietigt de TreeNode
	*/
	virtual ~TreeNode();

	/** 
	* Initialiseer het object aan de hand van de MeshDesc.
	* @param mDesh De MeshDesc.
	*/
	virtual void Init(const MeshDesc& mDesc) = 0;

	/** 
	* Draw tekent het object op het scherm.
	* @param effect Het effect met SchaduwVolume.
	* @param step 0 = Scene alleen met schaduw, 1 = Schaduw berekenen, 2 = Scene verlichten.
	*/
	virtual void Draw(EffectShadow* effectPtr, int step) {}

	/** 
	* De gewone draw voor de meshes met eigen effect en layout.
	*/
	virtual void Draw() {}

	/** 
	* De tick speciaal voor de skybox :)
	*/
	virtual void Tick(float dTime) {}

	/** 
	* Zet de world matrix op 0
	*/
	virtual void ResetWorldMatrix();
	/** 
	* Berekent de Worldmatrix
	*/
	virtual void GetTotalTranspose();

	/** 
	* @return De World matrix
	*/
	virtual D3DXMATRIX GetWorldMatrix();
	
	/** 
	* @return De Naam van het object
	*/
	virtual const tstring& GetName() const;

	/** 
	* Geef de Parent door aan de Child
	* @param parent De Parent pointer.
	*/
	virtual void AddParent(TreeNode* parent);

	/** 
	* @return De scale
	*/
	virtual const D3DXVECTOR3& GetScale() const;
	/** 
	* Zet de scaling
	* @param scale De scale
	*/
	virtual void SetScale(const D3DXVECTOR3& scale);
	/** 
	* Voeg toe aan de scaling
	* @param scale De scale
	*/
	virtual void AddScale(const D3DXVECTOR3& scale);

	/** 
	* @return De rotatie
	*/
	virtual const D3DXVECTOR3& GetRotation() const;
	/** 
	* Zet de rotatie
	* @param rot De rotatie.
	*/
	virtual void SetRotation(const D3DXVECTOR3& rot);
	/** 
	* Voeg toe aan de rotatie
	* @param rot De rotatie.
	*/
	virtual void AddRotation(const D3DXVECTOR3& rot);

	/** 
	* @return De translatie
	*/
	virtual const D3DXVECTOR3& GetTranslation() const;
	/** 
	* Zet de translatie
	* @param tran De translatie.
	*/
	virtual void SetTranslate(const D3DXVECTOR3& tran);
	/** 
	* Voeg toe aan de translatie
	* @param tran De translatie.
	*/
	virtual void AddTranslate(const D3DXVECTOR3& tran);

	/** 
	* Zet het Pivotpunt
	* @param pivot het Pivotpunt.
	*/
	virtual void SetPivot(const D3DXVECTOR3& pivot);

	/** 
	* Zegt dat dit object in een library zit en niet zomaar verwijderd mag worden.
	*/
	virtual void InLib();
	/** 
	* @return true als het object in een library zit.
	*/
	virtual bool IsInLib() const;

	/** 
	* @return De ShaderResource of Texture.
	*/
	virtual const ID3D10ShaderResourceView* GetTexture() const {return NULL;}

	/** 
	* @return De normal map
	*/
	virtual const ID3D10ShaderResourceView* GetNormalMap() const {return NULL;}

	/** 
	* @return De specular map
	*/
	virtual const ID3D10ShaderResourceView* GetSpecularMap() const {return NULL;}

	/** 
	* Geeft een kracht aan het object.
	*/
	virtual void AddForce(D3DXVECTOR3 force);

	/** 
	* @return True als het shaduwen maakt
	*/
	virtual bool CastShadow() const;

	/** 
	* Zet de afstand.
	* @param dist.
	*/
	virtual void SetDistance(float dist);
	/** 
	@return De afstand.
	*/
	virtual float GetDistance() const;

	/** 
	@return de Mesh descriptor
	*/
	virtual MeshDesc& GetDesc();

protected:
	virtual void Rotate(const D3DXVECTOR3& rot);
	virtual void Translate(const D3DXVECTOR3& tran);
	virtual void Scale(const D3DXVECTOR3& scale);

	MeshDesc m_MeshDesc;

	TreeNode* m_Parent;
	NxActor* m_Actor;
	bool m_Changed;

	D3DXMATRIX m_World, m_View, m_Proj;

	D3DXVECTOR3 m_Scale, m_Tran, m_Rot, m_Pivot;
	D3DXVECTOR3 m_DefScale, m_DefTran, m_DefRot;

	float m_Distance;

	TreeNode(const TreeNode &t);
	TreeNode& operator= (const TreeNode &t);
};
#endif // TreeNode_h__